#ifndef COORDGEODETIC_H
#define COORDGEODETIC_H

#include "util.h"

#include <string>
#include <sstream>
#include <iomanip>

namespace libsgp4
{

/**
 * @brief Stores a geodetic location (latitude, longitude, altitude).
 * 存大地位置（纬度、经度、海拔高度）
 * Internally the values are stored in radians and kilometres.
 */
struct CoordGeodetic
{
public:
    /**
     * Default constructor
     */
    CoordGeodetic() = default;

    /**
     * Constructor
     * @param[in] lat the latitude (degrees by default)
     * @param[in] lon the longitude (degrees by default)
     * @param[in] alt the altitude in kilometers
     * @param[in] is_radians whether the latitude/longitude is in radians
     * 默认经纬度单位是度，海拔单位是km，is_radians是表示经纬度是否为弧度制的布尔值
     */
    CoordGeodetic(
        double lat,
        double lon,
        double alt,
        bool is_radians = false)
    {
        if (is_radians)
        {
            latitude = lat;
            longitude = lon;
        }
        else
        {
            latitude = Util::DegreesToRadians(lat);
            longitude = Util::DegreesToRadians(lon);
        }
        altitude = alt;
    }

    /**
     * Copy constructor
     * @param[in] geo object to copy from
     */
    CoordGeodetic(const CoordGeodetic& geo)
    {
        latitude = geo.latitude;
        longitude = geo.longitude;
        altitude = geo.altitude;
    }

    /**
     * Assignment operator
     * @param[in] geo object to copy from
     */
    CoordGeodetic& operator=(const CoordGeodetic& geo)
    {
        if (this != &geo)
        {
            latitude = geo.latitude;
            longitude = geo.longitude;
            altitude = geo.altitude;
        }
        return *this;
    }

    /**
     * Dump this object to a string
     * @returns string
     */
    std::string ToString() const
    {
        std::stringstream ss;
        ss << std::right << std::fixed << std::setprecision(3);
        ss << "Lat: " << std::setw(8) << Util::RadiansToDegrees(latitude);
        ss << ", Lon: " << std::setw(8) << Util::RadiansToDegrees(longitude);
        ss << ", Alt: " << std::setw(10) << altitude;
        return ss.str();
    }

    /** latitude in radians (-PI >= latitude < PI) */
    double latitude{};
    /** latitude in radians (-PI/2 >= latitude <= PI/2) */
    double longitude{};
    /** altitude in kilometers */
    double altitude{};
};

/**
 * Dump a Coordgeodetic to a stream
 * @param[in,out] strm stream to output to
 * @param[in] g the CoordGeodetic to print
 */
inline std::ostream& operator<<(std::ostream& strm, const CoordGeodetic& g)
{
    return strm << g.ToString();
}

} // namespace libsgp4
#endif // COORDGEODETIC_H
